package com.gopay.common.trace.helper;

import com.gopay.common.trace.def.BinaryAnnotation;
import com.gopay.common.trace.def.Span;
import com.gopay.common.trace.enums.TraceType;
import com.gopay.common.trace.support.GenTraceId;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.protocol.HttpContext;

import java.util.Date;

/**
 * @author ddh02
 * @LogHttpClientHelper
 * @2017/5/19 13:53  www.gopay.com.cn Inc.All rights reserved.
 */


public class LogHttpClientHelper extends LogAbstractHelper {
    @Override
    public void before(Object... args) {

        try {

            HttpRequest httpRequest = (HttpRequest) args[0];
            HttpContext httpContext = (HttpContext) args[1];
            String url = (String) args[2];

           // count = logContext.incrCount();//当前线程计数加一

           /* if (StringUtils.isNotBlank(tid)) {  // 没有tid 就不记录

                //生成子span
                span = tracer.genSpan(tid, url, TraceType.HTTP_CLIENT);
                //设置 指标 cs 和cr
                tracer.clientSend(span, null, startTime);

                //httpContext.setAttribute("span", span);

                //设置header
                httpRequest.setHeader("tid", tid);
                httpRequest.setHeader("spanid", span.getId());
                //header上设置 来源
                httpRequest.setHeader("from", TraceType.HTTP_CLIENT.toString());
             }*/
             //modified by zyt,2017-12-25，解决定时任务，或将httpclient作为第一个拦截日志的点。的情况下，没有tid，不记录日志的问题，修改后，此种情况
            //新生成tid
            if(StringUtils.isBlank(tid)){
                tid = GenTraceId.genUUID();
                logContext.setTid(tid);
            }
            //生成子span
            span = tracer.genSpan(tid, url, TraceType.HTTP_CLIENT);
            count = logContext.incrCount();
            logContext.setSpan(count, span);
            //设置 指标 cs 和cr
            tracer.clientSend(span, null, startTime);

            //httpContext.setAttribute("span", span);

            //设置header
            httpRequest.setHeader("tid", tid);
            httpRequest.setHeader("spanid", span.getId());
            //header上设置 来源
            httpRequest.setHeader("from", TraceType.HTTP_CLIENT.toString());
        } catch (Exception e) {
            printSelfException(e, "httpclient before 阶段自身异常！");
        } finally {
        }
    }

    @Override
    public void after(Object... args) {

        try {

            HttpResponse httpResponse = (HttpResponse) args[0];
            //HttpContext httpContext = (HttpContext) args[1];

            if (span != null) {
                long end = System.currentTimeMillis();
                int code = httpResponse.getStatusLine().getStatusCode();
                logContext.dncrCount();
                Span ps = logContext.getSpan(logContext.getCount());
                /*if (ps != null) {
                    tracer.clientReceive(span, null, end);
                   // logContext.setSpan(count, span);  一定是没有下级调用的
                    ps.addChild(span);

                    if (code != HttpStatus.SC_OK) {
                        BinaryAnnotation binaryAnnotation = new BinaryAnnotation();
                        binaryAnnotation.setType(TraceType.HTTP_CLIENT.toString());
                        binaryAnnotation.setKey("http_status");
                        binaryAnnotation.setValue(code + "");
                        span.addBinaryAnnotation(binaryAnnotation);
                    }
                }*/
                //modified by zyt,2017-12-25,ps不存在的时候，也打印日志
                if (ps != null) {
                    //tracer.clientReceive(span, null, end);
                    // logContext.setSpan(count, span);  一定是没有下级调用的
                    ps.addChild(span);

                }
                tracer.clientReceive(span, null, end);  //ss
                if (code != HttpStatus.SC_OK) {
                    BinaryAnnotation binaryAnnotation = new BinaryAnnotation();
                    binaryAnnotation.setType(TraceType.HTTP_CLIENT.toString());
                    binaryAnnotation.setKey("http_status");
                    binaryAnnotation.setValue(code + "");
                    span.addBinaryAnnotation(binaryAnnotation);
                }
                tracer.endAndShow(span);
            }
        } catch (Exception e) {
            printSelfException(e, "httpclient after 阶段自身异常！");
        } finally {
           // logContext.dncrCount(); //执行完后 线程计数减一
        }
    }

    @Override
    public void ex(Throwable throwable) {

        try {
            if (span != null) {
                long end = System.currentTimeMillis();
                Span ps = logContext.getSpan(logContext.getCount());
                if (ps != null) {
                    tracer.clientReceive(span, null, end);
                    //添加异常
                    tracer.catchException(throwable, null, span);
                    ps.addChild(span);
                }
            }
        } catch (Exception ex) {
            printSelfException(ex, "httpclient ex 阶段自身异常！");
        } finally {
           // logContext.dncrCount(); //执行完后 线程计数减一
        }
    }

    @Override
    public TraceType getTraceType() {
        return TraceType.HTTP_CLIENT;
    }
}
